﻿using Core.Container;
using Core.Interface;
using Core.Log;
using Core.MessageEvent;
using DryIoc;
using ModBus.Mode;
using Prism.Commands;
using Prism.Events;
using Prism.Ioc;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Windows;
using System.Windows.Input;

namespace ModBus.ViewModels
{
    public class ModBusRTUViewModel : BindableBase
    {
        ModBusRTU modBusRTU;
        DataContainer<RTUParam> RTUParams;
        Container<ModBusDevice> container;
        Notify notifyCollect;
        public ModBusRTUViewModel(IContainerExtension container, IEventAggregator ea)
        {
            //获取所有的串口号
            notifyCollect = NotifyCollect.NotifyContainer["Error"];
            PortNames = new List<string>(SerialPort.GetPortNames());
            BaudRates = new List<int> { 4800, 9600, 19200, 38400, 57600, 115200 };
            StopBits = new List<StopBits> { System.IO.Ports.StopBits.None ,System.IO.Ports.StopBits.One,
            System.IO.Ports.StopBits.OnePointFive, System.IO.Ports.StopBits.Two };

            Paritys = new List<Parity> { Parity.Even, Parity.Mark, Parity.None, Parity.Odd };

            this.container = container.Resolve<Container<ModBusDevice>>("ModBusDevice");
            this.RTUParams = container.Resolve<DataContainer<RTUParam>>("RTUParams");
            ea.GetEvent<MessageEvent2>().Subscribe(Receive, ThreadOption.UIThread, false);
        }
     
        private void Receive(string key)
        {
            try
            {
                if (container.Get(key) is ModBusRTU rtu)
                {
                    modBusRTU = rtu;
                    if (modBusRTU != null)
                    {
                        PortName = modBusRTU.Param.PortName;
                        BaudRate = modBusRTU.Param.BaudRate;
                        DataBit = modBusRTU.Param.DataBit;
                        StopBit = modBusRTU.Param.StopBit;
                        Parity = modBusRTU.Param.Parity;
                    }
                }
            }
            catch (Exception ex)
            {
                notifyCollect.Add(ex.ToString());
            }
        }
    
        public List<string> PortNames { get; set; }
        private string portName;
        public string PortName
        {
            get { return portName; }
            set
            {
                SetProperty(ref portName, value, () =>
                {
                    modBusRTU.Param.PortName = portName;
                    RTUParams.Add(modBusRTU.Name, modBusRTU.Param);
                });
            }
        }

        public List<int> BaudRates { get; set; }
        private int baudRate;
        public int BaudRate
        {
            get { return baudRate; }
            set
            {
                SetProperty(ref baudRate, value, () =>
                {
                    modBusRTU.Param.BaudRate = baudRate;
                    RTUParams.Add(modBusRTU.Name, modBusRTU.Param);
                });
            }
        }

        private int dataBit;
        public int DataBit
        {
            get { return dataBit; }
            set
            {
                SetProperty(ref dataBit, value, () =>
                {
                    modBusRTU.Param.DataBit = dataBit;
                    RTUParams.Add(modBusRTU.Name, modBusRTU.Param);
                });
            }
        }

        public List<StopBits> StopBits { get; set; }
        private StopBits stopBit;
        public StopBits StopBit
        {
            get { return stopBit; }
            set
            {
                SetProperty(ref stopBit, value, () =>
                {
                    modBusRTU.Param.StopBit = stopBit;
                    RTUParams.Add(modBusRTU.Name, modBusRTU.Param);
                });
            }
        }

        public List<Parity> Paritys { get; set; }
        private Parity parity;
        public Parity Parity
        {
            get { return parity; }
            set
            {
                SetProperty(ref parity, value, () =>
                {
                    modBusRTU.Param.Parity = parity;
                    RTUParams.Add(modBusRTU.Name, modBusRTU.Param);
                });
            }
        }

        public ICommand ConnectCommand
        { get => new DelegateCommand(Connect); }
        private void Connect()
        {
            try
            {
                if (modBusRTU.Connect())
                    MessageBox.Show("连接成功");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        //断开连接
        public ICommand DisconnectCommand
        { get => new DelegateCommand(Disconnect); }
        private void Disconnect()
        {
            try
            {
                modBusRTU.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        #region
        private ushort uReadStartAdd;
        public ushort UReadStartAdd
        {
            get { return uReadStartAdd; }
            set { SetProperty(ref uReadStartAdd, value); }
        }

        private ushort uReadSize;
        public ushort UReadSize
        {
            get { return uReadSize; }
            set { SetProperty(ref uReadSize, value); }
        }

        private string uReadValue;
        public string UReadValue
        {
            get { return uReadValue; }
            set { SetProperty(ref uReadValue, value); }
        }
        public ICommand ReadUshort
        { get => new DelegateCommand(ReadUshortMethod); }
        private void ReadUshortMethod()
        {
            try
            {
                if (UReadSize == 0) UReadSize = 1;
                modBusRTU.ReadRegister(UReadStartAdd, UReadSize, out ushort[] values);
                UReadValue = string.Join("，", values);
            }
            catch (Exception ex)
            {
                notifyCollect.Add(ex.ToString());
            }       
        }

        private ushort uWriteStartAdd;
        public ushort UWriteStartAdd
        {
            get { return uWriteStartAdd; }
            set { SetProperty(ref uWriteStartAdd, value); }
        }
        private ushort uWriteSize;
        public ushort UWriteSize
        {
            get { return uWriteSize; }
            set { SetProperty(ref uWriteSize, value); }
        }
        private string uWriteValue;
        public string UWriteValue
        {
            get { return uWriteValue; }
            set { SetProperty(ref uWriteValue, value); }
        }
        public ICommand WriteUshort
        { get => new DelegateCommand(WriteUshortMethod); }
        private void WriteUshortMethod()
        {
            try
            {
                if (UWriteValue == null) return;
                string[] values = UWriteValue?.Split(new char[2] { ',', '，' });
                var ushorts = Array.ConvertAll(values, ushort.Parse);
                if (UWriteSize == 0) UWriteSize = 1;
                if (modBusRTU.WriteRegister(UWriteStartAdd, UWriteSize, ushorts))
                { MessageBox.Show("写入成功"); }
            }
            catch (Exception ex)
            {
                notifyCollect.Add(ex.ToString());
            }          
        }


        private ushort fReadStartAdd;
        public ushort FReadStartAdd
        {
            get { return fReadStartAdd; }
            set { SetProperty(ref fReadStartAdd, value); }
        }

        private ushort fReadSize;
        public ushort FReadSize
        {
            get { return fReadSize; }
            set { SetProperty(ref fReadSize, value); }
        }

        private string fReadValue;
        public string FReadValue
        {
            get { return fReadValue; }
            set { SetProperty(ref fReadValue, value); }
        }
        public ICommand ReadFloat
        { get => new DelegateCommand(ReadFloatMethod); }
        private void ReadFloatMethod()
        {
            try
            {
                if (FReadSize == 0) FReadSize = 1;
                modBusRTU.ReadFloat(FReadStartAdd, FReadSize, out float[] values);
                FReadValue = string.Join("，", values);
            }
            catch (Exception ex)
            {
                notifyCollect.Add(ex.ToString());
            }       
        }


        private ushort fWriteStartAdd;
        public ushort FWriteStartAdd
        {
            get { return fWriteStartAdd; }
            set { SetProperty(ref fWriteStartAdd, value); }
        }
        private ushort fWriteSize;
        public ushort FWriteSize
        {
            get { return fWriteSize; }
            set { SetProperty(ref fWriteSize, value); }
        }
        private string fWriteValue;
        public string FWriteValue
        {
            get { return fWriteValue; }
            set { SetProperty(ref fWriteValue, value); }
        }
        public ICommand WriteFloat
        { get => new DelegateCommand(WriteFloatMethod); }
        private void WriteFloatMethod()
        {
            try
            {
                string[] values = FWriteValue.Split(new char[2] { ',', '，' });
                var floats = Array.ConvertAll(values, float.Parse);
                if (FWriteSize == 0) FWriteSize = 1;
                if (modBusRTU.WriteFloat(FWriteStartAdd, FWriteSize, floats))
                { MessageBox.Show("写入成功"); }
            }
            catch (Exception ex)
            {
               notifyCollect.Add(ex.ToString());
            }        
        }
        #endregion
    }
}
